﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using UserDefineForm.formcomponent;
using UserDefineForm.control.propertymapping;

namespace UserDefineForm.control
{
    public enum Modes { Design, Run };
    public enum ControlType { TextBox,NumberTextBox,CheckBox,RadioButton,DatePicker,ComboBox };

    public abstract partial class DesignableControlBase : UserControl
    {
        #region member


        protected const int MINWIDTH = 20;

        protected Control control;

        #region property for design

        protected Point oldPointerLocation;

        protected DesignPanel designPanel;

        protected PropertiesPanelv2 propPnl;

        protected Modes mode= Modes.Design;

        protected MappingObjectBase mappingObject;

        public MappingObjectBase MappingObject
        {
            get
            {
                mappingObject.setControl(this);
                return mappingObject;
            }
            
        }

        private bool selected = false;

        protected bool Selected
        {
            get { return selected; }
            set 
            {
                selected = value;
                if (selected)
                {
                    designPanel.selectControl(this);
                    propPnl.setControl(this);
                }
                else
                {
                    designPanel.unSelectControl(this);
                }
                 
            }
        }

        protected virtual bool IsResizable
        {
            get { return true; }
            
        }

        protected bool isMoving;
        public bool IsMoving
        {
            get { return isMoving; }
            set { isMoving = value; }
        }

        private bool isResizing;

        public bool IsResizing
        {
            get { return isResizing; }
            set { isResizing = value; }
        }

        public Modes Mode
        {
            get { return mode; }
            set 
            { 
                mode = value;
                
                if (mode == Modes.Design)
                {
                    mainPnl.Enabled = false;
                }
                else
                {
                    mainPnl.Enabled = true;
                }
            }
        }
        #endregion

        #region property of control

        protected int id;

        public int Id
        {
            get { return id; }
            set { id = value; }
        }
        protected int formId;

        public int FormId
        {
            get { return formId; }
            set { formId = value; }
        }

        protected String defaultValue="";

        public String DefaultValue
        {
            get { return defaultValue; }
            set { defaultValue = value; }
        }


        public Font FontProp
        {
            set
            {
                control.Font = value;
            }

            get
            {
                return control.Font;
            }
        }

        public abstract String Value { get; set; }

        public virtual List<string> ListValue
        {
            get { return null; }
            set{}
        }

        #endregion

        #endregion

        public DesignableControlBase()
        {
        }

        public DesignableControlBase(DesignPanel designPanel,PropertiesPanelv2 propPnl)
        {
            InitializeComponent();
            this.designPanel = designPanel;
            this.propPnl = propPnl;
            this.Mode = Modes.Design;
            setMouseEvent();
        }



        private void setMouseEvent()
        {
            
            resizePnl.MouseHover += new EventHandler(this.resizePnl_MouseHover);
            resizePnl.MouseLeave += new EventHandler(resizePnl_MouseLeave);
            resizePnl.MouseDown += new MouseEventHandler(resizePnl_MouseDown);
            resizePnl.MouseUp += new MouseEventHandler(resizePnl_MouseUp);
            /*
            movePnl.MouseHover += new EventHandler(movePnl_MouseHover);
            movePnl.MouseLeave += new EventHandler(movePnl_MouseLeave);
            movePnl.MouseDown += new MouseEventHandler(movePnl_MouseDown);
            movePnl.MouseUp += new MouseEventHandler(movePnl_MouseUp);
            */
            this.MouseHover += new EventHandler(movePnl_MouseHover);
            this.MouseLeave += new EventHandler(movePnl_MouseLeave);
            this.MouseDown += new MouseEventHandler(movePnl_MouseDown);
            this.MouseUp += new MouseEventHandler(movePnl_MouseUp);
            
                /*
            else
            {
                resizePnl.MouseHover -= new EventHandler(this.resizePnl_MouseHover);
                resizePnl.MouseLeave -= new EventHandler(resizePnl_MouseLeave);
                resizePnl.MouseDown -= new MouseEventHandler(resizePnl_MouseDown);
                resizePnl.MouseUp -= new MouseEventHandler(resizePnl_MouseUp);
                
                movePnl.MouseHover -= new EventHandler(movePnl_MouseHover);
                movePnl.MouseLeave -= new EventHandler(movePnl_MouseLeave);
                movePnl.MouseDown -= new MouseEventHandler(movePnl_MouseDown);
                movePnl.MouseUp -= new MouseEventHandler(movePnl_MouseUp);
                
                this.MouseHover -= new EventHandler(movePnl_MouseHover);
                this.MouseLeave -= new EventHandler(movePnl_MouseLeave);
                this.MouseDown -= new MouseEventHandler(movePnl_MouseDown);
                this.MouseUp -= new MouseEventHandler(movePnl_MouseUp);
            }
        */
        }

  
        /*
        protected void setUnResizable()
        {
            resizePnl.MouseHover -= new EventHandler(this.resizePnl_MouseHover);
            resizePnl.MouseLeave -= new EventHandler(resizePnl_MouseLeave);
            resizePnl.MouseDown -= new MouseEventHandler(resizePnl_MouseDown);
            resizePnl.MouseUp -= new MouseEventHandler(resizePnl_MouseUp);
        }
        */
        protected bool isInsidePanel(Point loc)
        {

            return (loc.X >= 0 && loc.X < designPanel.Size.Width && loc.Y >= 0 && loc.Y < designPanel.Size.Height);

        }

        public abstract ControlType getType();

        #region event handler

        protected void movePnl_MouseUp(object sender, MouseEventArgs e)
        {
            if (Mode == Modes.Run) return;
            

            if (!IsMoving)
            {
                return;
            }

            Point newLocationInPanel = new Point(this.Location.X + e.X - oldPointerLocation.X, this.Location.Y + e.Y - oldPointerLocation.Y);

            if (isInsidePanel(newLocationInPanel))
            {
                this.Location = newLocationInPanel;
                designPanel.Refresh();
                propPnl.refreshInfo();
            }
        }

        protected void movePnl_MouseDown(object sender, MouseEventArgs e)
        {
            if (Mode == Modes.Run) return;
            this.Selected = true;

            oldPointerLocation = e.Location;
            IsMoving = true;
            IsResizing = false;
        }

        protected void resizePnl_MouseUp(object sender, MouseEventArgs e)
        {
            if (!IsResizable || Mode == Modes.Run) return;

            if (!IsResizing)
            {
                return;
            }

            Point newLocationInPanel = new Point(resizePnl.Location.X + e.X, resizePnl.Location.Y + e.Y);
            int newWidth = e.X + resizePnl.Location.X;

            if (isInsidePanel(newLocationInPanel) && newWidth >= MINWIDTH)
            {
                if (newWidth < MINWIDTH)
                {
                    newWidth = MINWIDTH;
                }
                this.Size = new Size(newWidth, this.Size.Height);
                designPanel.Refresh();
                propPnl.refreshInfo();
            }
        }

        protected void resizePnl_MouseDown(object sender, MouseEventArgs e)
        {
            if (!IsResizable || Mode == Modes.Run) return;
            this.Selected = true;
            IsResizing = true;
            IsMoving = false;
        }

        protected void movePnl_MouseLeave(object sender, EventArgs e)
        {
            if (Mode == Modes.Run) return;

            this.Cursor = Cursors.Arrow;
        }

        protected void movePnl_MouseHover(object sender, EventArgs e)
        {
            if (Mode == Modes.Run) return;

            this.Cursor = Cursors.SizeAll;
        }

        protected void resizePnl_MouseLeave(object sender, EventArgs e)
        {
            if (!IsResizable || Mode == Modes.Run) return;

            this.Cursor = Cursors.Arrow;
        }

        protected void resizePnl_MouseHover(object sender, EventArgs args)
        {
            if (!IsResizable || Mode== Modes.Run) return;

            this.Cursor = Cursors.SizeWE;
        }

        #endregion
    }
}
